#include <PiPei.h>
#include <Uefi.h> 
#include <Library/UefiLib.h> 
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>

#include <InstallHashPpi.h>
#include <Pi/PiHob.h>


EFI_STATUS
EFIAPI
PeiServiceInstallPpiEntryPoint (
  IN       EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES          **PeiServices
  )
{
  EFI_STATUS                                         Status = EFI_SUCCESS;
  EFI_PEI_PPI_DESCRIPTOR                             *FvInfoPpiDescriptor;
  EDKII_PEI_FIRMWARE_VOLUME_INFO_STORED_HASH_FV_PPI  *StoredHashFvPpi;
  UINTN                                              PpiSize;
  EFI_BOOT_MODE  BootMode;
  UINT8 InitialHashValue[64];

  DEBUG ((DEBUG_ERROR, "---------------PeiServiceInstallPpiEntryPoint Call----------------- \n"));
  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);
  
  PpiSize = sizeof (EDKII_PEI_FIRMWARE_VOLUME_INFO_STORED_HASH_FV_PPI);

  StoredHashFvPpi = AllocatePool (PpiSize);
  ASSERT (StoredHashFvPpi != NULL);

  StoredHashFvPpi->HashInfo.HashFlag   |= FV_HASH_FLAG_BOOT_MODE (BootMode);
  StoredHashFvPpi->HashInfo.HashAlgoId  = PcdGet16(gMyInstallPpisHashAlgoId);
  StoredHashFvPpi->HashInfo.HashSize    = PcdGet16(gMyInstallPpisHashSize);

  UINT64 HashValue0 = PcdGet64(gMyInstallPpisHashValue0);
  UINT64 HashValue1 = PcdGet64(gMyInstallPpisHashValue1);
  UINT64 HashValue2 = PcdGet64(gMyInstallPpisHashValue2);
  UINT64 HashValue3 = PcdGet64(gMyInstallPpisHashValue3);
  UINT64 HashValue[4] = {HashValue0,HashValue1,HashValue2,HashValue3};
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < sizeof(UINT64); j++) {
      InitialHashValue[i * sizeof(UINT64) + j] = (UINT8)(HashValue[i] >> ((sizeof(UINT64) - j - 1) * 8)) & 0xFF;
    }
  }
//   UINT8 InitialHashValue[64] = {
//   0xEF, 0xBC, 0x59, 0x0C, 0x66, 0x60, 0x29, 0xDC,
//   0x7C, 0x27, 0xAE, 0x56, 0xB9, 0xE8, 0xE9, 0xFE,
//   0x16, 0xB9, 0xDC, 0x23, 0x14, 0xCE, 0x55, 0xB6,
//   0x11, 0x0B, 0xE8, 0xFE, 0xDC, 0xD8, 0x31, 0x3C
// };
  // 使用 CopyMem 来将 InitialHashValue 复制到 Hash 数组
  CopyMem((VOID *)(StoredHashFvPpi->HashInfo.Hash), InitialHashValue, StoredHashFvPpi->HashInfo.HashSize);
  
  StoredHashFvPpi->FvNumber             = PcdGet8(gMyInstallPpisFvNumber);
  StoredHashFvPpi->FvInfo->Base         = PcdGet32(gMyInstallPpisFvBase);
  StoredHashFvPpi->FvInfo->Length       = PcdGet32(gMyInstallPpisFvLength);
  StoredHashFvPpi->FvInfo->Flag         = PcdGet64(gMyInstallPpisFvFlag);

  FvInfoPpiDescriptor = AllocatePool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
  ASSERT (FvInfoPpiDescriptor != NULL);

  FvInfoPpiDescriptor->Guid  = &gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid;
  FvInfoPpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
  FvInfoPpiDescriptor->Ppi   = (VOID *)StoredHashFvPpi;

  Status = PeiServicesInstallPpi (FvInfoPpiDescriptor);
  ASSERT_EFI_ERROR (Status);
  return Status;
}
